import * as XLSX from 'xlsx'

/**
 * Excel读取类
 * @author: Savitar
 * @datetime: 2021-10-14
 */

const A = 65
export class ExcelReader {
  constructor(file, sheet) {
    this.file = file
    this.excelData = null
    this.mergeMap = {}
    this.read(sheet)
  }

  read(sheet) {
    //拿到所导入文件的名字
    const fileName = this.file
    //定义reader，存放文件读取方法
    const reader = new FileReader()
    //启动函数
    reader.readAsBinaryString(fileName)
    //onload在文件被读取时自动触发
    reader.onload = (e) => {
      //workbook存放excel的所有基本信息
      const workbook = XLSX.read(e.target.result, { type: 'binary' });
      //定义sheetList中存放excel表格的sheet表，就是最下方的tab
      let worksheet = workbook.Sheets[workbook.SheetNames[sheet]]; // 只能通过工作表名称来获取指定工作表
      this.excelData = worksheet
      this.initMerge()
    }
  }

  /**
   * 初始合并单元格
   * excel合并单元格后默认只有左上角的单元格保留值 此方法会将所有合并的单元格都赋值
   */



  initMerge() {
    const merges = this.excelData['!merges'];
    if (!merges) return
    merges.forEach(p => {
      let columnIndex = p['s']['c']
      const endColumn = p['e']['c']
      let rowIndex = p['s']['r']
      const endRow = p['e']['r']
      const startColumn = createCol(p['s']['c'])
      const startRow = p['s']['r'] + 1
      while (columnIndex <= endColumn) {
        rowIndex = p['s']['r']
        while (rowIndex <= endRow) {
          let column = createCol(columnIndex);
          let row = rowIndex + 1
          this.mergeMap[column + row] = this.excelData[startColumn + startRow]['v']
          rowIndex++
        }
        columnIndex++
      }

    })
  }

  toArray(titleLine = 1, startRow = 1, startColumn = 'A', alias = null, endRow = 999) {
    if (this.excelData == null || !this.excelData) {
      return []
    }
    const resultArr = []
    let length;
    if (this.excelData['!rows'] && this.excelData['!rows'].length) {
      length = this.excelData['!rows'].length
    } else {
      length = endRow;
    }

    for (let i = startRow; i <= length; i++) {
      const item = {}
      let column = startColumn
      let columnIndex = startColumn.charCodeAt()
      do {
        //拿到属性名
        let attrName = ''
        if (this.excelData[column + titleLine]) {
          attrName = this.excelData[column + titleLine]['v']
        } else {
          attrName = this.mergeMap[column + titleLine]
        }

        //如果设置了别名
        if (alias != null) {
          let prev = ''
          if (alias.prevLine && alias.prevLine > 0) {
            prev = this.mergeMap[column + alias.prevLine] + '-'
          }
          attrName = alias.getAlias(prev + attrName)
        }
        if (this.excelData[column + i]) {
          item[attrName] = this.excelData[column + i]['v']
        } else {
          item[attrName] = ''
        }
        column = this.chartAdd(columnIndex)
        columnIndex++
      } while (this.excelData[column + titleLine])
      resultArr.push(item)
    }
    return resultArr

  }

  chartAdd(columnIndex) {
    return createCol(columnIndex - A)
  }
}

function createCol(n) {
  const ordA = 'A'.charCodeAt(0)
  const ordZ = 'Z'.charCodeAt(0)
  const len = ordZ - ordA + 1
  let str = ""
  while (n >= 0) {
    str = String.fromCharCode(n % len + ordA) + str
    n = Math.floor(n / len) - 1
  }
  return str
}

/***
 * 别名map
 */
export class AliasMap {
  constructor(map = {}, prevLine) {
    this.map = map;
    this.prevLine = prevLine
  }

  getAlias(name) {
    return this.map[name] || name
  }

}

